package cn.tedu.tmall.admin.mall.service.impl;

import cn.tedu.tmall.admin.mall.dao.persist.repository.ICategoryRepository;
import cn.tedu.tmall.admin.mall.pojo.entity.Category;
import cn.tedu.tmall.admin.mall.pojo.param.CategoryAddNewParam;
import cn.tedu.tmall.admin.mall.pojo.vo.CategoryListItemVO;
import cn.tedu.tmall.admin.mall.pojo.vo.CategoryStandardVO;
import cn.tedu.tmall.admin.mall.service.ICategoryService;
import cn.tedu.tmall.common.enumerator.ServiceCode;
import cn.tedu.tmall.common.ex.ServiceException;
import cn.tedu.tmall.common.pojo.vo.PageData;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.sql.rowset.serial.SerialException;
import java.io.Serializable;
import java.util.List;

@Service
public class CategoryServiceImpl implements ICategoryService {

    // 自动装配Repository
    @Autowired
    private ICategoryRepository categoryRepository;
    // 先从Repository中补充"根据ID查询类别详情"的方法(已完成)
    // 先在Repository中补充"根据类别名称统计类别的数量"的方法(已完成)

    @Autowired
    private RedisTemplate<String, Serializable> redisTemplate;

    @Override
    @Transactional
    public void addNew(CategoryAddNewParam categoryAddNewParam) {
        CategoryStandardVO parentCategory = null;
        // 判断parentId的值是否不为0
        Long parentId = categoryAddNewParam.getParentId();
        if (parentId != 0){
            // 是: 调用Repository根据parentId查询父级类别的详情
            parentCategory = categoryRepository.getStandardById(parentId);
            // -- 判断查询结果是否为null
            if (parentCategory == null){
                // -- 是: 抛出异常
                throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,"新增类别失败,父级类别不存在!");
            } else {
                // -- 否: 判断父级类别的enable是否为0
                if (parentCategory.getEnable() == 0){
                    // -- -- 是: 抛出异常
                    throw new ServiceException(ServiceCode.ERROR_CONFLICT, "新增类别失败，父级类别已经被禁用!");
                }
            }
        }

        // 从参数中获取本次尝试新增的类别的名称
        String name = categoryAddNewParam.getName();
        // 调用Repository根据名称统计数量
        int countByName = categoryRepository.countByName(name);
        // 判断统计结果是否大于0
        if (countByName > 0) {
            // 是: 抛出异常
            throw new ServiceException(ServiceCode.ERROR_CONFLICT, "新增类别失败，类别名已经被占用!");
        }

        // 确定depth的值: 判断parentId的值是否为0
        Integer depth;
        if (parentId == 0){
            // 是: depth固定位1
            depth = 1;
        } else {
            // 否: depth父级类别的depth+1
            depth = parentCategory.getDepth() + 1;
        }

        // 创建实体类 (Category) 对象
        Category category = new Category();
        // 将参数的各属性值复制到实体对象中
        BeanUtils.copyProperties(categoryAddNewParam,category);
        // 补全实体对象中的属性值: depth, isParent(0)
        category.setDepth(depth);
        category.setIsParent(0);
        // 调用Repository执行插入数据(实体)
        int rows = categoryRepository.insert(category);
        if (rows != 1) {
            throw new ServiceException(ServiceCode.ERROR_INSERT, "新增类别失败，服务器忙,请稍后再试!"); //事务回滚
        }

        // 在方法上添加@Transactional以观察效果(添加在接口上更安全)
        //"".substring(10000); //StringIndexOutOfBoundsException

        // 当父级存在,且父级类别的isParent为0时,需要将父级类别的isParent从0改为1
        if(parentCategory != null && parentCategory.getIsParent() == 0) {
            Category updateParentCategory = new Category();
            updateParentCategory.setId(parentId);
            updateParentCategory.setIsParent(1);
            rows = categoryRepository.updateById(updateParentCategory);
            if (rows != 1) {{
                throw new ServiceException(ServiceCode.ERROR_UPDATE, "新增类别失败，服务器忙,请稍后再试!"); //事务回滚
            }}
        }
    }

    @Override
    public CategoryStandardVO getStandardById(Long id) {
        CategoryStandardVO queryResult = categoryRepository.getStandardById(id);
        if (queryResult == null) {
            String message = "获取类别详情失败,尝试访问的数据不存在!";
            throw new ServiceException(ServiceCode.ERROR_NOT_FOUND,message);
        }
        return queryResult;
    }

    @Override
    public PageData<CategoryListItemVO> listByParent(Long parentId, Integer pageNum, Integer pageSize) {
        return categoryRepository.listByParent(parentId,pageNum,pageSize);
    }

    @Override
    public void saveList(Long id, List<CategoryStandardVO> categoryList) {
        String key = KEY_CATEGORY_LIST_BY_ID + id;
        ListOperations<String, Serializable> opsForList = redisTemplate.opsForList();
        for (CategoryStandardVO categoryStandardVO : categoryList) {
            opsForList.rightPush(key,categoryStandardVO);
        }
        SetOperations<String, Serializable> opsForSet = redisTemplate.opsForSet();
        opsForSet.add(KEY_ALL_KEYS,key);
    }

}
